home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / ACORNUSERS / EMULATOR / MAGICKIT / assembler / c / main < prev    next >
Text File  |  1998-04-27  |  7KB  |  354 lines

  1.  
  2. /*  Assembler for the HuC6280 microprocessor found in the PC Engine console.
  3.  *  ----
  4.  *  This program was originaly a 6502 assembler written by
  5.  *  J. H. Van Ornum, it has been modified by David Michel
  6.  *  to support the HuC6280.
  7.  *
  8.  *  This program is freeware. You are free to distribute, use and
  9.  *  modifiy it as you wish.
  10.  *
  11.  *  Enjoy!
  12.  */
  13.  
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include "defs.h"
  17. #include "externs.h"
  18. #include "vars.h"
  19.  
  20. /***** DEFINES *************/
  21.  
  22. /***** GLOBALS *************/
  23.  
  24. int    infile_error;
  25. int    infile_num;
  26. int    switch_throwback;
  27. char   i_file[128];
  28. char   o_file[128];
  29. char   l_file[128];
  30. FILE  *iptr;
  31. FILE  *optr;
  32. FILE  *lptr;
  33. struct t_input_info input_file[8];
  34. /*----------------*/
  35.  
  36. int field[] = {
  37.     SFIELD,
  38.     SFIELD + 8,
  39.     SFIELD + 14,
  40.     SFIELD + 14,
  41.     SFIELD + 14,
  42.     SFIELD + 14,
  43. /*     SFIELD + 23, */
  44. /*     SFIELD + 43, */
  45. /*     SFIELD + 75 */
  46. };
  47.  
  48. /***** EXTERNALS ***********/
  49.  
  50. /*
  51.  *  main :
  52.  *  -----
  53.  *
  54.  */
  55.  
  56. main(int argc, char **argv)
  57. {
  58.     char *p;
  59.     int i, usage = 1;
  60.  
  61.         i_file[0] = o_file[0] = l_file[0] = 0;
  62.         switch_throwback = 0;
  63.         for (i = 1; i < argc && usage; i++) {
  64.             if (!strcmp(argv[i], "-o")) strcpy(o_file, argv[++i]);
  65.             else if (!strcmp(argv[i], "-throwback")) switch_throwback = 1;
  66.             else if (argv[i][0] != '-') {
  67.                 if (i_file[0] == 0) strcpy(i_file, argv[i]);
  68.                 else if (l_file[0] == 0) strcpy(l_file, argv[i]);
  69.                 else usage = 0;
  70.             }
  71.             else usage = 0;
  72.         }
  73.         if (usage == 0 || o_file[0] == 0 || i_file[0] == 0) {
  74.             fprintf(stderr, "Syntax: magicasm <source file> -o <output file> [-throwback] [<list file>]\n");
  75.             return(1);
  76.         }
  77.         if (l_file[0] == 0) strcpy(l_file, "null:$.l_file");
  78.  
  79.     /* --  auto-add the file extensions. */
  80.  
  81. /*    strupr(i_file);*/
  82.  
  83. /*    if (p = strrchr(i_file, '.')) {
  84.         if (!strchr(p, '\\'))
  85.            *p = '\0';
  86.         else
  87.             p = NULL;
  88.     }
  89.  
  90.     strcpy(o_file, i_file);
  91.     strcpy(l_file, i_file);
  92.     strcat(o_file, ".PCE");
  93.     strcat(l_file, ".LST");
  94.  
  95.     if (p)
  96.        *p = '.';
  97.     else
  98.         strcat(i_file, ".ASM");*/
  99.  
  100.     /* --  open the input file. */
  101.  
  102.     if (open_input(i_file)) {
  103.         fprintf(stdout, "Can not open input file '%s'!\n", i_file);
  104.         exit(1);
  105.     }
  106.  
  107.     /* --  clear the code array. */
  108.  
  109.     memset(rom, 8192 * 128, 0);
  110.  
  111.     /* --  assemble. */
  112.  
  113.     for (i = 0; i < 256; i++) {
  114.         hash_tbl[i] = NULL;
  115.         macro_tbl[i] = NULL;
  116.     }
  117.  
  118.     for (pass = FIRST_PASS; pass <= LAST_PASS; pass++) {
  119.         infile_error = -1;
  120.         errcnt = 0;
  121.         page = 0;
  122.         bank = 0;
  123.         max_bank = 0;
  124.         loccnt = 0;
  125.         slnum = 0;
  126.         mcounter = 0;
  127.         mcntmax = 0;
  128.         clist = 0;
  129.         mlist = 0;
  130.         glablptr = NULL;
  131.         rsbase = 0;
  132.  
  133.         for (i = 0; i < 128; i++) {
  134.             bank_offset[i] = 0;
  135.             bank_page[i] = 0;
  136.         }
  137.         while (readline() != -1) {
  138.             assemble();
  139.             if (loccnt > 0x2000) {
  140.                 error("Out of range, bank offset > $1FFF!");
  141.                 break;
  142.             }
  143.         }
  144.         if (errcnt) {
  145.                 if (switch_throwback == 2) {
  146.                     DDEUtils_ThrowbackEnd();
  147.                     switch_throwback = 1;
  148.                 }
  149.             fprintf(stdout, "# %d ERROR(s)\n", errcnt);
  150.             break;
  151.         }
  152.  
  153.         rewind(iptr);
  154.  
  155.         if (pass == FIRST_PASS) {
  156.             if (xlist) {
  157.                 if ((lptr = fopen(l_file, "w")) == NULL) {
  158.                     fprintf(stdout, "Can not open listing file '%s'!\n", l_file);
  159.                     exit(1);
  160.                 }
  161.                 fprintf(lptr, "#[1]   %s\n", input_file[1].name);
  162.             }
  163.         }
  164.     }
  165.  
  166.     if (errcnt == 0) {
  167.         if ((optr = fopen(o_file, "wb")) == NULL) {
  168.             fprintf(stdout, "Can not open object file '%s'!\n", o_file);
  169.             exit(1);
  170.         }
  171.         fwrite(rom, 8192, max_bank + 1, optr);
  172.         fclose(optr);
  173.     }
  174.     if (xlist)
  175.         fclose(lptr);
  176.     fclose(iptr);
  177.     return(0);
  178. }
  179.  
  180. /*
  181.  * readline :
  182.  * ---------
  183.  * reads and formats an input line.
  184.  *
  185.  */
  186.  
  187. readline()
  188. {
  189.     char *ptr, *arg, num[8];
  190.     int j, n;
  191.     int    i;        /* pointer into prlnbuf */
  192.     int    c;        /* current character        */
  193.     int    temp;    /* temp used for line number conversion */
  194.  
  195. start:
  196.     for (i = 0; i < LAST_CH_POS; i++)
  197.         prlnbuf[i] = ' ';
  198.  
  199.     /*  if expand_macro get line from macro buffer */
  200.  
  201.     if (expand_macro) {
  202.         if (mlptr == NULL) {
  203.             while (mlptr == NULL) {
  204.                 midx--;
  205.                 mlptr = mstack[midx];
  206.                 mcounter = mcntstack[midx];
  207.                 if (midx == 0) {
  208.                     mlptr = NULL;
  209.                     expand_macro = 0;
  210.                     break;
  211.                 }
  212.             }
  213.         }
  214.         if (mlptr) {
  215.             i = SFIELD;
  216.             ptr = mlptr->data;
  217.             while (c = *ptr++) {
  218.                 if (c != '\\')
  219.                     prlnbuf[i++] = c;
  220.                 else {
  221.                     c = *ptr++;
  222.                     prlnbuf[i] = '\0';
  223.                     if (c == '@') {
  224.                         n = 4;
  225.                         sprintf(num, "%04i", mcounter);
  226.                         arg = num;
  227.                     }
  228.                     else if (c >= '1' && c <= '9') {
  229.                         j   = c - '1';
  230.                         n   = strlen(marg[midx][j]);
  231.                         arg = marg[midx][j];
  232.                     }
  233.                     else {
  234.                         error("Invalid macro argument index!");
  235.                         return (-1);
  236.                     }
  237.                     if ((i + n) >= LAST_CH_POS - 1) {
  238.                         error("Invalid line length!");
  239.                         return (-1);
  240.                     }
  241.                     strncpy(&prlnbuf[i], arg, n);
  242.                     i += n;
  243.                 }
  244.                 if (i >= LAST_CH_POS - 1)
  245.                     i =  LAST_CH_POS - 1;
  246.             }
  247.             prlnbuf[i] = '\0';
  248.             mlptr = mlptr->next;
  249.             return (0);
  250.         }
  251.     }
  252.  
  253.     /*  put source line number into prlnbuf. */
  254.  
  255.     i = 4;
  256.     temp = ++slnum;
  257.     while (temp != 0) {
  258.         prlnbuf[i--] = temp % 10 + '0';
  259.         temp /= 10;
  260.     }
  261.     i = SFIELD;
  262.     while ((c = getc(iptr)) != '\n') {
  263.         if(c == '\r')
  264.             continue;
  265.         prlnbuf[i++] = c;
  266.         if (c == '\t') {
  267.             prlnbuf[--i] = ' ';
  268.             i += (8 - ((i - SFIELD) % 8));
  269.         }
  270.         else if (c == EOF) {
  271.             if (close_input())
  272.                 return(-1);
  273.             goto start;
  274.         }
  275.         if (i >= LAST_CH_POS - 1)
  276.             i =  LAST_CH_POS - 1;
  277.     }
  278.     prlnbuf[i] = '\0';
  279.     return(0);
  280. }
  281.  
  282. /*
  283.  * open_input :
  284.  * -----------
  285.  * open an input file, up to 7 levels.
  286.  *
  287.  */
  288.  
  289. open_input(char *name)
  290. {
  291.     FILE *fptr;
  292.     char *p;
  293.     int i;
  294.  
  295.     if (infile_num == 7) {
  296.         error("Too many include levels!");
  297.         return (1);
  298.     }
  299.     if (infile_num) {
  300.         input_file[infile_num].lnum = slnum;
  301.         input_file[infile_num].fptr = iptr;
  302.     }
  303.     strcpy(i_file, name);
  304. /*    strupr(i_file);
  305.  
  306.     if (p = strrchr(i_file, '.')) {
  307.         if (strchr(p, '\\'))
  308.             strcat(i_file, ".ASM");
  309.     } else
  310.         strcat(i_file, ".ASM");*/
  311.     if (infile_num) {
  312.         for (i = 1; i < infile_num; i++) {
  313.             if (!strcmp(input_file[i].name, i_file)) {
  314.                 error("Repeated include file!");
  315.                 return (1);
  316.             }
  317.         }
  318.     }
  319.     if ((fptr = fopen(i_file, "r")) == NULL)
  320.         return (-1);
  321.  
  322.     iptr = fptr;
  323.     slnum = 0;
  324.     infile_num++;
  325.     input_file[infile_num].fptr = fptr;
  326.     strcpy(input_file[infile_num].name, i_file);
  327.     if ((pass == LAST_PASS) && (xlist))
  328.         fprintf(lptr, "#[%i]   %s\n", infile_num, input_file[infile_num].name);
  329.     return (0);
  330. }
  331.  
  332. /*
  333.  * close_input :
  334.  * ------------
  335.  * close an input file, return -1 if no more files in the stack.
  336.  *
  337.  */
  338.  
  339. close_input()
  340. {
  341.     if (infile_num <= 1)
  342.         return (-1);
  343.  
  344.     fclose(iptr);
  345.     infile_num--;
  346.     infile_error = -1;
  347.     slnum = input_file[infile_num].lnum;
  348.     iptr = input_file[infile_num].fptr;
  349.     if ((pass == LAST_PASS) && (xlist))
  350.         fprintf(lptr, "#[%i]   %s\n", infile_num, input_file[infile_num].name);
  351.     return (0);
  352. }
  353.  
  354.